//********************************************************************************************************************//
//ORGANIZATION:
//AUTHOR: bpeng(bogers.peng@gmail.com)
//SUMMARY:
//********************************************************************************************************************//
#ifndef NATIVE_SYSTEM_BASE_STRING_H
#define NATIVE_SYSTEM_BASE_STRING_H

#ifndef NATIVE_SYSTEM_BASE_OBJECT_H
#include "System/Base/Object.h"
#endif
#ifndef NATIVE_SYSTEM_BASE_COMPARE_H
#include "System/Base/Compare.h"
#endif
#ifndef NATIVE_SYSTEM_BASE_EQUALTO_H
#include "System/Base/EqualTo.h"
#endif
#ifndef NATIVE_SYSTEM_BASE_EXCEPTION_H
#include "System/Base/Exception.h"
#endif

namespace Native { namespace System
{
    //****************************************************************************************************************//
    //CString
    //
    //****************************************************************************************************************//
    NATIVE_DECLARE_CONST_OBJECT(CString, C_STRING);
    class NATIVE_LIBRARY_EXPORT CString :
        public CObject,
        public IEqualTo<CString>,
        public ICompare<CString>,
        public ICompare<wstring>,
        public ICompare<mstring>
    {
        NATIVE_DECLARE_OBJECT;

    public:
        static const size_t END = -1;
        static const size_t MISS = -1;

    protected:
        wstring _content;

    public:
        CString();
        CString(C_STRING& that);
        CString(C_STRING&& that);
        CString(WSTRING& content);
        CString(MSTRING& content);
        CString(const wchar_t* content);
        virtual ~CString();

        //{CObject
        virtual wstring ToString() const;
        //}
        //{IEqualTo
        virtual bool operator==(C_STRING& rvalue) const;
        virtual bool operator!=(C_STRING& rvalue) const;
        //}
        //{ICompare<CString>
        virtual bool operator>(C_STRING& rvalue) const;
        virtual bool operator<(C_STRING& rvalue) const;
        virtual bool operator>=(C_STRING& rvalue) const;
        virtual bool operator<=(C_STRING& rvalue) const;
        //}
        //{ICompare<wstring>
        virtual bool operator>(WSTRING& rvalue) const;
        virtual bool operator<(WSTRING& rvalue) const;
        virtual bool operator>=(WSTRING& rvalue) const;
        virtual bool operator<=(WSTRING& rvalue) const;
        //}
        //{ICompare<mstring>
        virtual bool operator>(MSTRING& rvalue) const;
        virtual bool operator<(MSTRING& rvalue) const;
        virtual bool operator>=(MSTRING& rvalue) const;
        virtual bool operator<=(MSTRING& rvalue) const;
        //}
        size_t Length() const;
        bool Empty() const;
        CString Substring(size_t location, size_t length=END) const throw();
        C_STRING& Append(WSTRING& tail);
        C_STRING& Append(C_STRING& tail);
        C_STRING& Append(const wchar_t* tail);
        C_STRING& Append(wchar_t tail);
        vector<CString> Split(wchar_t separator) const;
        CString ToLower() const;
        CString ToUpper() const;
        CString TrimLeft(wchar_t scrap) const;
        CString TrimRight(wchar_t scrap) const;
        CString Trim(WSTRING& scraps) const;
        size_t Find(C_STRING& keyword) const;
        size_t FindFirst(C_STRING& keyword) const;
        wchar_t Head() const;
        wchar_t Tail() const;
        CWSTRING ToCString() const;

        C_STRING& operator=(C_STRING& rvalue);
        wchar_t& operator[](size_t index) throw();
        wchar_t operator[](size_t index) const throw();
        bool operator==(WSTRING& rvalue) const;
        bool operator==(MSTRING& rvalue) const;
        bool operator!=(WSTRING& rvalue) const;
        bool operator!=(MSTRING& rvalue) const;
    };
    //****************************************************************************************************************//
    //CEmptyStringException
    //
    //****************************************************************************************************************//
    NATIVE_DECLARE_CONST_OBJECT(CEmptyStringException, EMPTY_STRING_EXCEPTION);
    class NATIVE_LIBRARY_EXPORT CEmptyStringException :
        public CException
    {
        NATIVE_DECLARE_OBJECT;

        static void Check(
            C_SCENE& scene,
            C_STRING& string,
            WSTRING& arguments = EMPTY_STRING,
            WSTRING& detail=EMPTY_STRING) throw();
        
    protected:
        CEmptyStringException();

    public:
        CEmptyStringException(EMPTY_STRING_EXCEPTION& that);
        CEmptyStringException(EMPTY_STRING_EXCEPTION&& that);
        CEmptyStringException(
            C_SCENE& scene,
            WSTRING& arguments = EMPTY_STRING,
            WSTRING& detail = EMPTY_STRING);
    };
}}

#endif